﻿using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.IO;

namespace QAQ
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private bool ImClient = false;
        private int lastState;
        private int LastRoomId;
        private int LastConfiguredRoomID;
        private bool findForward; 


        private ImgProc mImgProc = null;
        private GameCtrl mGameCtrl =null;
        private IntPtr mProcessHandle =IntPtr.Zero;
        public static bool mSpeStateConfigured = false; //TODO:.bad
        public static bool mBadass=true;
        private int UknownWait;

        

        private bool Enable=false;

        private void Form1_Load(object sender, EventArgs e)
        {
            mImgProc = new ImgProc();
            mGameCtrl = new GameCtrl();
            

            lastState = ImgProc.STA_Unknown;
            findForward = true;            
            UknownWait = 0;

            //Gma.UserActivityMonitor.HookManager.KeyDown += OnKeyDownEventListener;

            this.timer1.Start();           
        }

        private void OnKeyDownEventListener(object o,KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.End:
                    this.checkBox1.Checked = false;
                    //this.Enable = false;
                    break;
            }
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            mProcessHandle = User32.FindWindow("D3D Window", "GrandChase Eternal v1.05.62 (20090120)");

            if (mProcessHandle != IntPtr.Zero)
            {
                label1.Text = "Detected";
                this.timer1.Stop(); 
                this.timer2.Start();                
            }
            else
            {
                label1.Text = "I am linstening...";
            }
      
        }
        private void fsm_Server()
        {
            if (mImgProc.state == ImgProc.STA_Unknown)
            {
                UknownWait++;
                if (UknownWait > 10)
                {
                    mGameCtrl.MouseGoAway(mProcessHandle);
                    mGameCtrl.PressEnter(mProcessHandle);
                    UknownWait = 0;
                }
            }
            else
            {
                UknownWait = 0;
                switch (mImgProc.mState[mImgProc.state].staname)
                {
                    case "isServerReady":
                        if (ServerStarted == true && false == mGCPacketSocServer.isValid() )
                        {
                            mGCPacketSocServer.clear();
                        }
                        if (ServerStarted == true && mGCPacketSocServer.isEmpty == true)
                        {
                            mGCPacketSocServer.SetId(mImgProc.mCurrentRoomId);
                            mGCPacketSocServer.mStringPasswd = mGCPacketSocServer.GenerateKey(mImgProc.mCurrentRoomId);
                        }
                        if (false == mSpeStateConfigured)
                        {
                            mGameCtrl.ConfigRoom(mProcessHandle);
                        }
                        if (true == mBadass)
                        {
                            mGameCtrl.ConfigRoom(mProcessHandle);
                        }
                           
                
                        break;
                    case "isCompeteDone":
                        mGameCtrl.ExitGame(mProcessHandle);
                        break;
                    case "isGetAward":
                        mGameCtrl.PressEnter(mProcessHandle);
                        break;
                    case "isP2Ready":
                        mGameCtrl.ReadyToGo(mProcessHandle);                        
                        mGCPacketSocServer.clear();
                        break;
                    case "isInLobby":                        
                        mGameCtrl.GoClickCreatRoom(mProcessHandle);
                        mSpeStateConfigured = false;
                        break;
                    case "isInRoom":
                        if (LastRoomId == mImgProc.mCurrentRoomId)
                        {
                            if (ServerStarted == true && false == mGCPacketSocServer.isValid())
                            {
                                mGCPacketSocServer.clear();
                            }
                            if (ServerStarted == true && mGCPacketSocServer.isEmpty == true)
                            {
                                mGCPacketSocServer.SetId(mImgProc.mCurrentRoomId);
                                mGCPacketSocServer.mStringPasswd = mGCPacketSocServer.GenerateKey(mImgProc.mCurrentRoomId);
                            }
                            if (true == mBadass)
                            {
                                mGameCtrl.ConfigRoom(mProcessHandle);
                            }
                        }
                        else
                        {
                            if (true == mBadass)
                            {
                                mGameCtrl.ConfigRoom(mProcessHandle);
                            }
                            if (false == mSpeStateConfigured)
                            {
                                mGameCtrl.ConfigRoom(mProcessHandle);
                            }
                        }
                        break;                    
                    case "isPromptExit":
                        mGameCtrl.PressEnter(mProcessHandle);                        
                        break;
                    case "isConfiguring":
                        //////////////Experimential
                        if (ServerStarted == true && false == mGCPacketSocServer.isValid())
                        {
                            mGCPacketSocServer.clear();
                        }
                        if (ServerStarted == true && mGCPacketSocServer.isEmpty == true)
                        {
                            mGCPacketSocServer.SetId(mImgProc.mCurrentRoomId);
                            mGCPacketSocServer.mStringPasswd = mGCPacketSocServer.GenerateKey(mImgProc.mCurrentRoomId);
                        }
                        //////////////Experimential//
                        mGameCtrl.CreateRoomFocusPWForm(mProcessHandle);
                        mGameCtrl.EnterPassword(mProcessHandle, mGCPacketSocServer.GenerateKey(mImgProc.mCurrentRoomId) );
                        LastConfiguredRoomID=mImgProc.mCurrentRoomId;
                        mSpeStateConfigured = true;
                        mBadass = false;
                        break;
                    case "isDefaultSetting":
                        mGameCtrl.ChangeCompeteType(mProcessHandle);
                        LastConfiguredRoomID = mImgProc.mCurrentRoomId;
                        break;
                        
                    case "isCreatingRoom":
                        mGameCtrl.CreateRoomFocusPWForm(mProcessHandle);
                        mGameCtrl.EnterPassword(mProcessHandle,mGCPacketSocServer.GenerateKey(LastRoomId));
                        
                        break;
                    case "isLoading":
                        LastRoomId = LastConfiguredRoomID;
                        break;
                    default:
                        break;
                }
            }
        }
        private void fsm_Client()
        {
            if (mImgProc.state == ImgProc.STA_Unknown)
            {
                UknownWait++;
                if (UknownWait > 10)
                {
                    mGameCtrl.MouseGoAway(mProcessHandle);
                    mGameCtrl.PressEnter(mProcessHandle);
                    UknownWait = 0;
                }
            }
            else
            {
                UknownWait = 0;
                switch (mImgProc.mState[mImgProc.state].staname)
                {
                    case "isGetAward":
                        mGameCtrl.PressEnter(mProcessHandle);
                        break;
                    case "isInGame":
                        mGameCtrl.ExitGame(mProcessHandle);
                        break;
                    case "isInLobby":
                        if (false == mGCPacketSocClient.isValid())
                        {
                            break;
                        }
                        
                        if (true == mImgProc.mVTargetRoomIndex)
                        {
                            mGameCtrl.EnterRoom(mProcessHandle, mImgProc.mTargetRoomIndex);
                        }
                        else{
                            if( true == mImgProc.isEndOfPage ){
                                findForward=!findForward;
                            }
                            if( true == findForward ){
                                mGameCtrl.NtPage(mProcessHandle);
                            }else{
                                mGameCtrl.PrPage(mProcessHandle);
                            }
                        }
                        break;
                    case "isDefaultSetting":
                    case "isServerReady":
                    case "isInRoom":
                        if (mImgProc.mCurrentRoomId == mImgProc.mTargetRoomId)
                        {
                            mGameCtrl.ReadyToGo(mProcessHandle);
                        }
                        else
                        {
                            mGameCtrl.LeaveRoom(mProcessHandle);
                        }
                        break;
                    case "isLoading":
                        break;
                    case "isPromptExit":
                        mGameCtrl.PressEnter(mProcessHandle);
                        findForward = true;
                        mGCPacketSocClient.clear();
                        mImgProc.mTargetRoomId = -2;

                        break;
                    case "isPromptPassword":                        
                        mGameCtrl.FocusPWForm(mProcessHandle);
                        mGameCtrl.EnterPassword(mProcessHandle, mGCPacketSocClient.mStringPasswd);
                        this.textBox2.Text = mGCPacketSocClient.mStringPasswd;
                        break;
                    case "isCreatingRoom":
                        break;
                    case "isWtfError":
                        mGameCtrl.PressEnter(mProcessHandle);
                        break;
                    case "isWrongPW":
                        SocClient.badass = true;
                        mGameCtrl.PressEnter(mProcessHandle);
                        break;

                    default:
                        break;
                }
            }
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            try
            {
                mImgProc.fetchImg(mProcessHandle);
            }
            catch (Exception exc)
            {                
                this.timer2.Enabled = false;
                this.timer1.Enabled = true;
                return;
            }
            mImgProc.Update();
            

            try
            {
                if (true == ImClient && true == ClientStarted && mImgProc.mState[mImgProc.state].staname == "isInLobby")
                {
                    int i = 0;
                    do
                    {
                        i++;
                        mGCPacketSocClient.clear();
                        mImgProc.mTargetRoomId = mGCPacketSocClient.GetIdBlocking();
                    } while (false == mGCPacketSocClient.isValid());
                    
                    this.textBox1.Text = mImgProc.mTargetRoomId.ToString();
                    this.label3.Text = "";
                    if (i > 1)
                    {
                        return;
                    }
                }

            }
            catch (Exception exc)
            {
                if (true == ImClient)
                {
                    this.label3.Text = exc.Message.ToString();
                    return;
                }
            }


            /*
            if (false == ImClient && true == ServerStarted)
            {
                mGCPacketSocServer.SetId(mImgProc.mCurrentRoomId);
                mGCPacketSocServer.mStringPasswd = mGCPacketSocServer.GenerateKey(mImgProc.mCurrentRoomId);
            }*/

            
            if (false == ClientStarted && false == ServerStarted)
            {
                return;
            }
            
            ////show state
            if (mImgProc.state == ImgProc.STA_Unknown)
            {
                this.Text = "Unknown";
            }
            else
            {
                this.Text = mImgProc.mState[mImgProc.state].staname;   
            }
            
            if (false == Enable)
            {
                return;
            }


            //fsm
            if (true == ImClient)
            {   
                fsm_Client();
            }
            else
            {
                fsm_Server();
            }
            lastState = mImgProc.state;
        }
        private class User32
        {
            [DllImport("user32.dll")]
            public static extern IntPtr FindWindow(String sClassName, String sAppName);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            Enable = this.checkBox1.Checked;
        }


        SocServer mSocServer;
        GCPacket mGCPacketSocServer;
        bool ServerStarted = false;
        private void button1_Click(object sender, EventArgs e)
        {
            this.ImClient = false;
            if( ServerStarted== false){
                mGCPacketSocServer = new GCPacket();
                mSocServer = new SocServer(mGCPacketSocServer , Convert.ToInt32(this.textBox4.Text));
            
                ServerStarted=true;
            }
            {
                mGCPacketSocServer.SetId(-3);
                mGCPacketSocServer.mStringPasswd = mGCPacketSocServer.GenerateKey(-3);
            }
        }
        bool ClientStarted=false;
        SocClient mSocClient;
        GCPacket mGCPacketSocClient;
        private void button2_Click(object sender, EventArgs e)
        {
            this.ImClient = true;
            if (ClientStarted == false)
            {
                ClientStarted = true;
                mGCPacketSocClient= new GCPacket();
                mSocClient = new SocClient(mGCPacketSocClient, this.textBox3.Text, Convert.ToInt32(this.textBox4.Text));
            }
            mGCPacketSocClient.clear();
            this.textBox1.Text = mGCPacketSocClient.GetIdBlocking().ToString();
            this.textBox2.Text = mGCPacketSocClient.mStringPasswd;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (mSocServer != null)
            {
                mSocServer.Dispose();
            }
            if (mSocClient != null)
            {
                mSocClient.Dispose();
            }
        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            if (this.mGameCtrl != null && this.mGameCtrl.mJoyControl!=null)
            {                
                this.mGameCtrl.mJoyControl.id = Convert.ToUInt32(this.textBox5.Text);
            }
        }
    }
}
